package manager.http;



import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.util.CharsetUtil;
import manager.connection.ClientConnectionManager;
import manager.pay.GetPayResult;
import manager.pay.HandleNotify;
import manager.pay.state.ConsumptionType;
import manager.pay.type.PayResultInfo;
import manager.qrcode.WXQrcode;
import util.MyFactory;
import util.ResultTypeList;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import advice.ExceptionManager;
import database.DBService;



import database.pojo.UserRechargeInfo;

/**
 * 
* Title: NettyServerHandler
* Description: 处理支付回调
* @version 0.0.1  
* @author zk
* @date 2018-4-17
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
	private static Logger logger = Logger.getLogger(ExceptionManager.class);
	
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

		if(! (msg instanceof FullHttpRequest)){
			return;
	 	}
		FullHttpRequest httpRequest = (FullHttpRequest)msg;
		try{
			String path=httpRequest.uri();
			String outTradeNo="";
			if (path.contains("WXPay")) {
				//System.out.println("this weixinPay");
				
				Map<String, String> outMap = parseOutTradeNoOfWeiXin(httpRequest);
				outTradeNo = outMap.get("out_trade_no");
				String consumptionType =outMap.get("attach");
				//System.out.println("consumptionType"+consumptionType);
				logger.info("weixinPay: consumptionType: "+consumptionType);
				if( "".equals(outTradeNo)  || "".equals(consumptionType)) {
					return ;
				}
				if("1".equals(consumptionType)) {
					MyFactory.context.getBean("HandleNotify", HandleNotify.class).HandleWeixinPayAndZhifubaoPay(outTradeNo);
				}else if ("2".equals(consumptionType)) {
					MyFactory.context.getBean("HandleNotify", HandleNotify.class).HandleKweixingAndKZhifubao(outTradeNo);
				}else {
					System.out.println("NO KWON ConsumptionType");
					return ;
				}
			} else if (path.contains("AliPay")) {
				//System.out.println("this aliPay");
				outTradeNo = parseOutTradeNoOfAliPay(httpRequest);
				logger.info("aliPay outTradeNo:"+outTradeNo);
				if(outTradeNo == null || outTradeNo =="") {
					return ;
				}			
				MyFactory.context.getBean("HandleNotify", HandleNotify.class).HandleWeixinPayAndZhifubaoPay(outTradeNo);
			}else if (path.contains("KCoinOfAli")) {
				//System.out.println("this is KCoinOfAli");
				outTradeNo = parseOutTradeNoOfAliPay(httpRequest);
				logger.info("KCoinOfAli outTradeNo:"+outTradeNo);
				if(outTradeNo == null || outTradeNo =="") {
					return ;
				}
				MyFactory.context.getBean("HandleNotify", HandleNotify.class).HandleKweixingAndKZhifubao(outTradeNo);
				
			}else if (path.contains("MidActivate")) {
				//System.out.println("THIS is midActivate:");
				logger.info("MidActivate ");
				MyFactory.context.getBean("ClientConnectionManager",ClientConnectionManager.class).ntfMidActivate(getBody(httpRequest));
				
			}
			else {
				System.out.println("NO KWON HTTP REQ");
				logger.info("NO KWON HTTP REQ");
				return ;
			}
		}catch(Exception e){
			System.out.println("处理请求失败!");
			e.printStackTrace();
		}finally{
			//释放请求
			httpRequest.release();
		}
	}
	
	private void send(ChannelHandlerContext ctx, String context,HttpResponseStatus status,String path) {
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(context, CharsetUtil.UTF_8));
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, path);
		ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}
 
	/**
     * 解析请求参数
     * @return 包含所有请求参数的键值对, 如果没有参数, 则返回空
     *
     * @throws BaseCheckedException
     * @throws IOException
     */
    public String parseOutTradeNoOfAliPay(FullHttpRequest fullReq) throws IOException  {
        HttpMethod method = fullReq.method();

       int sigin = ResultTypeList.UNKNOWN_FAIL;
       Map<String, String> dateMap = new HashMap<>();
       if (HttpMethod.POST == method) {
            // 是POST请求
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullReq);
            decoder.offer(fullReq);

            List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();
            for (InterfaceHttpData parm : parmList) {

                Attribute data = (Attribute) parm;
                if("trade_status".equals(data.getName()) && "TRADE_SUCCESS".equals(data.getValue())) {
                	sigin =ResultTypeList.SUCCESS;
                }
                dateMap.put(data.getName(), data.getValue());
                //System.out.println("data.getName:"+data.getName());
               //System.out.println("data.getValue---------:"+data.getValue());                                            	
            }
        }
       if (sigin == ResultTypeList.SUCCESS) {
    	   return dateMap.get("out_trade_no");
	} else {
		return null;
	}
    } 
    
    private String getBody(FullHttpRequest request){
    	HttpMethod method = request.method();
    	if (HttpMethod.POST == method) {
    		ByteBuf buf = request.content();
    		return buf.toString(CharsetUtil.UTF_8);
    	  }else {
    		//System.out.println("not post method");
    		  logger.info("not post method");
			return null;
		}
    	
		
	}
       public Map<String, String> parseOutTradeNoOfWeiXin(FullHttpRequest fullReq) throws Exception  {
    	  // System.out.println("parseOutTradeNoOfWeiXin");	
    	   ByteBuf buf = fullReq.content();
    	    Map<String, String> notifyMap = xmlToMap(buf.toString(CharsetUtil.UTF_8));
    	    if (MyFactory.context.getBean("WXQrcode",WXQrcode.class).SignaTure(notifyMap)) {
    	    	return notifyMap;
			}
   				return null;
           }
       /**
        * XML格式字符串转换为Map
        *
        * @param strXML XML字符串
        * @return XML数据转换后的Map
        * @throws Exception
        */
       public static Map<String, String> xmlToMap(String strXML) throws Exception {
           Map<String, String> data = new HashMap<String, String>();
           DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
           DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
           InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
           org.w3c.dom.Document doc = documentBuilder.parse(stream);
           doc.getDocumentElement().normalize();
           NodeList nodeList = doc.getDocumentElement().getChildNodes();
           for (int idx=0; idx<nodeList.getLength(); ++idx) {
               Node node = nodeList.item(idx);
               if (node.getNodeType() == Node.ELEMENT_NODE) {
                   org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                   data.put(element.getNodeName(), element.getTextContent());
                   //System.out.println("element.getNodeName():"+element.getNodeName()+": element.getTextContent()"+element.getTextContent());
               }
           }
           try {
               stream.close();
           }
           catch (Exception ex) {

           }
           return data;
       }
	
	
	
	
}
